package com.android.basiclib.engine.permission

import android.app.Activity
import android.content.Context
import android.content.res.Configuration
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.text.TextUtils
import android.view.Gravity
import android.view.LayoutInflater
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.PopupWindow
import android.widget.TextView
import com.android.basiclib.R
import com.android.basiclib.view.dialog.FangIOSDialog
import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.OnPermissionInterceptor
import com.hjq.permissions.OnPermissionPageCallback
import com.hjq.permissions.Permission
import com.hjq.permissions.PermissionFragment
import com.hjq.permissions.XXPermissions
import com.hjq.toast.Toaster

class PermissionInterceptor : OnPermissionInterceptor {
    /**
     * 权限申请标记
     */
    private var mRequestFlag = false

    /**
     * 权限申请说明 Popup
     */
    private var mPermissionPopup: PopupWindow? = null

    /**
     * 发起权限申请
     */
    override fun launchPermissionRequest(activity: Activity, allPermissions: List<String>, callback: OnPermissionCallback?) {
        mRequestFlag = true
        val deniedPermissions = XXPermissions.getDenied(activity, allPermissions)
        val message = activity.getString(R.string.common_permission_message, PermissionNameConvert.getPermissionString(activity, deniedPermissions))
        val decorView = activity.window.decorView as ViewGroup
        val activityOrientation = activity.resources.configuration.orientation
        var showPopupWindow = activityOrientation == Configuration.ORIENTATION_PORTRAIT
        for (permission in allPermissions) {
            if (!XXPermissions.isSpecial(permission)) {
                continue
            }
            if (XXPermissions.isGranted(activity, permission)) {
                continue
            }
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R &&
                TextUtils.equals(Permission.MANAGE_EXTERNAL_STORAGE, permission)
            ) {
                continue
            }
            // 如果申请的权限带有特殊权限，并且还没有授予的话
            // 就不用 PopupWindow 对话框来显示，而是用 Dialog 来显示
            showPopupWindow = false
            break
        }
        if (showPopupWindow) {
            PermissionFragment.launch(activity, ArrayList(allPermissions), this, callback)
            // 延迟 300 毫秒是为了避免出现 PopupWindow 显示然后立马消失的情况
            // 因为框架没有办法在还没有申请权限的情况下，去判断权限是否永久拒绝了，必须要在发起权限申请之后
            // 所以只能通过延迟显示 PopupWindow 来做这件事，如果 300 毫秒内权限申请没有结束，证明本次申请的权限没有永久拒绝
            HANDLER.postDelayed({
                if (!mRequestFlag) {
                    return@postDelayed
                }
                if (activity.isFinishing || activity.isDestroyed) {
                    return@postDelayed
                }
                showPopupWindow(activity, decorView, message)
            }, 300)
        } else {

            // 特殊权限的弹窗提示
            val fangIOSDialog = FangIOSDialog(activity)
            fangIOSDialog.setTitle(R.string.common_permission_description)
            fangIOSDialog.setMessage(message)
            fangIOSDialog.setNegativeButton(R.string.common_permission_denied) {
                fangIOSDialog.dismiss()
                if (callback == null) {
                    return@setNegativeButton
                }
                callback.onDenied(deniedPermissions, false)
            }
            fangIOSDialog.setPositiveButton(R.string.common_permission_granted) {
                fangIOSDialog.dismiss()
                PermissionFragment.launch(
                    activity, ArrayList(allPermissions),
                    this@PermissionInterceptor, callback
                )
            }
            fangIOSDialog.setCanceledOnTouchOutside(true)
            fangIOSDialog.show()
        }
    }

    /**
     * 用户授予了权限,无需特殊处理
     */
    override fun grantedPermissionRequest(
        activity: Activity, allPermissions: List<String>,
        grantedPermissions: List<String>, allGranted: Boolean,
        callback: OnPermissionCallback?
    ) {
        if (callback == null) {
            return
        }
        callback.onGranted(grantedPermissions, allGranted)
    }

    /**
     * 用户拒绝了权限
     */
    override fun deniedPermissionRequest(
        activity: Activity, allPermissions: List<String>,
        deniedPermissions: List<String>, doNotAskAgain: Boolean,
        callback: OnPermissionCallback?
    ) {
        callback?.onDenied(deniedPermissions, doNotAskAgain)
        if (doNotAskAgain) {
            if (deniedPermissions.size == 1 && Permission.ACCESS_MEDIA_LOCATION == deniedPermissions[0]) {
                Toaster.show(R.string.common_permission_media_location_hint_fail)
                return
            }
            showPermissionSettingDialog(activity, allPermissions, deniedPermissions, callback)
            return
        }
        if (deniedPermissions.size == 1) {
            val deniedPermission = deniedPermissions[0]
            val backgroundPermissionOptionLabel = getBackgroundPermissionOptionLabel(activity)
            if (Permission.ACCESS_BACKGROUND_LOCATION == deniedPermission) {
                Toaster.show(activity.getString(R.string.common_permission_background_location_fail_hint, backgroundPermissionOptionLabel))
                return
            }
            if (Permission.BODY_SENSORS_BACKGROUND == deniedPermission) {
                Toaster.show(activity.getString(R.string.common_permission_background_sensors_fail_hint, backgroundPermissionOptionLabel))
                return
            }
        }
        val message: String
        val permissionNames = PermissionNameConvert.permissionsToNames(activity, deniedPermissions)
        message = if (permissionNames.isNotEmpty()) {
            activity.getString(
                R.string.common_permission_fail_assign_hint,
                PermissionNameConvert.listToString(activity, permissionNames)
            )
        } else {
            activity.getString(R.string.common_permission_fail_hint)
        }
        Toaster.show(message)
    }

    override fun finishPermissionRequest(
        activity: Activity, allPermissions: List<String>,
        skipRequest: Boolean, callback: OnPermissionCallback?
    ) {
        mRequestFlag = false
        dismissPopupWindow()
    }

    private fun showPopupWindow(activity: Activity, decorView: ViewGroup, message: String) {
        if (mPermissionPopup == null) {
            val contentView = LayoutInflater.from(activity).inflate(R.layout.permission_description_popup, decorView, false)
            mPermissionPopup = PopupWindow(activity)
            mPermissionPopup!!.contentView = contentView
            mPermissionPopup!!.width = WindowManager.LayoutParams.MATCH_PARENT
            mPermissionPopup!!.height = WindowManager.LayoutParams.WRAP_CONTENT
            mPermissionPopup!!.animationStyle = android.R.style.Animation_Dialog
            mPermissionPopup!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
            mPermissionPopup!!.isTouchable = true
            mPermissionPopup!!.isOutsideTouchable = true
        }
        val messageView = mPermissionPopup!!.contentView.findViewById<TextView>(R.id.tv_permission_description_message)
        messageView.text = message
        // 注意：这里的 PopupWindow 只是示例，没有监听 Activity onDestroy 来处理 PopupWindow 生命周期
        mPermissionPopup!!.showAtLocation(decorView, Gravity.TOP, 0, 0)
    }

    private fun dismissPopupWindow() {
        if (mPermissionPopup == null) {
            return
        }
        if (!mPermissionPopup!!.isShowing) {
            return
        }
        mPermissionPopup!!.dismiss()
    }

    /**
     * 用户拒绝了权限，弹窗提示他
     */
    private fun showPermissionSettingDialog(
        activity: Activity?, allPermissions: List<String>,
        deniedPermissions: List<String>, callback: OnPermissionCallback?
    ) {
        if (activity == null || activity.isFinishing || activity.isDestroyed) {
            return
        }
        var message: String? = null
        val permissionNames = PermissionNameConvert.permissionsToNames(activity, deniedPermissions)
        if (permissionNames.isNotEmpty()) {
            if (deniedPermissions.size == 1) {
                val deniedPermission = deniedPermissions[0]
                if (Permission.ACCESS_BACKGROUND_LOCATION == deniedPermission) {
                    message = activity.getString(R.string.common_permission_manual_assign_fail_background_location_hint, getBackgroundPermissionOptionLabel(activity))
                } else if (Permission.BODY_SENSORS_BACKGROUND == deniedPermission) {
                    message = activity.getString(R.string.common_permission_manual_assign_fail_background_sensors_hint, getBackgroundPermissionOptionLabel(activity))
                }
            }
            if (TextUtils.isEmpty(message)) {
                message = activity.getString(
                    R.string.common_permission_manual_assign_fail_hint,
                    PermissionNameConvert.listToString(activity, permissionNames)
                )
            }
        } else {
            message = activity.getString(R.string.common_permission_manual_fail_hint)
        }

        val fangIOSDialog = FangIOSDialog(activity)
        fangIOSDialog.setTitle(R.string.common_permission_alert)
        fangIOSDialog.setMessage(message)
        fangIOSDialog.setNegativeButton(R.string.common_permission_denied) { fangIOSDialog.dismiss() }
        fangIOSDialog.setPositiveButton(R.string.common_permission_goto_setting_page) {
            fangIOSDialog.dismiss()

            //去应用设置页面手动授权权限
            XXPermissions.startPermissionActivity(activity, deniedPermissions, object : OnPermissionPageCallback {
                override fun onGranted() {
                    callback?.onGranted(allPermissions, true)
                }

                override fun onDenied() {
                    showPermissionSettingDialog(activity, allPermissions, XXPermissions.getDenied(activity, allPermissions), callback)
                }
            })

        }
        fangIOSDialog.setCanceledOnTouchOutside(true)
        fangIOSDialog.show()
    }

    /**
     * 获取后台权限的《始终允许》选项的文案
     */
    private fun getBackgroundPermissionOptionLabel(context: Context): String {
        var backgroundPermissionOptionLabel = ""
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            backgroundPermissionOptionLabel = context.packageManager.backgroundPermissionOptionLabel.toString()
        }
        if (TextUtils.isEmpty(backgroundPermissionOptionLabel)) {
            backgroundPermissionOptionLabel = context.getString(R.string.common_permission_background_default_option_label)
        }
        return backgroundPermissionOptionLabel
    }

    companion object {
        val HANDLER = Handler(Looper.getMainLooper())
    }

}
